/*
	Node Class
	Author: Lukasz Iwanski
*/

#pragma once

#include <list>
#include <hash_map>
#include <d3dx9.h>

#include <Entity.h>
#include <EntityManager.h>
#include <AnimationPlayer.h>

class Node : public Entity
{
public:
	//public state - why not?
	enum nodeOwner {
		NEUTRAL,
		ENEMY,
		PLAYER,
		FINISH

	};

	enum hackedState {
		HACKED,
		HACKING,
		NOTHACKED
	};

	enum secureState {
		SECURED,
		SECURING,
		NOTSECURED
	};
private: 
	int ID;
	int weight; //level of node - how dificult is it to hack it
	D3DXVECTOR3 position;

	std::list<Node*> connectedNodes;
	nodeOwner owner;
	
	hackedState hacking;
	secureState securing;


	int level;

	float hackingTimeleft;
	float securingTimeleft;

	int distance;


	//animations
	AnimationPlayer* anims;

	//conections 
	std::hash_map<Node*, float> connections;
	bool stillMoney;
	
public:
	void setStillMoney(bool b) { stillMoney = b; }
	bool canStillMoney() { return stillMoney; }
	Node(void){};
	~Node(void){ delete anims; };


	// Constructor gets animations, position, and node owner
	Node(AnimationPlayer* newAnims, D3DXVECTOR3 pos, nodeOwner newowner)
		: Entity(pos, 0, "Node"),
		anims(newAnims)
	{
		this->position = pos;
		this->weight = 1;
		this->distance = 2;
		this->owner = newowner;
		this->level = 2;
		this->hackingTimeleft = level;
		this->securingTimeleft = level;

		hacking = hackedState::NOTHACKED;
		securing = secureState::NOTSECURED;
		stillMoney = true;
		if(owner == nodeOwner::PLAYER)
		{
			anims->playAnimation("playerBaseIdleAnim");

			setTexture(anims->getCurrentAnimation()->getTexture());

		}else if(owner == nodeOwner::FINISH) {
			anims->playAnimation("finishBaseIdleAnim");

			setTexture(anims->getCurrentAnimation()->getTexture());
		}else if(owner == nodeOwner::ENEMY) {
			anims->playAnimation("enemyBaseIdleAnim");

			setTexture(anims->getCurrentAnimation()->getTexture());
		}else {
			//add animation for neutral nones entity
			//anims->playAnimation("NutralNodeAnimation");
			anims->playAnimation("nutralNodeAnim");
			setTexture(anims->getCurrentAnimation()->getTexture());
		}
	}
	
	Node(std::string name, AnimationPlayer* newAnims, D3DXVECTOR3 pos, nodeOwner newowner)
		: Entity(pos, 0, name),
		anims(newAnims)
	{
		this->position = pos;
		this->weight = 1;
		this->distance = 2;
		this->owner = newowner;
		this->level = 1;
		this->hackingTimeleft = level;
		this->securingTimeleft = level;

		hacking = hackedState::NOTHACKED;
		securing = secureState::NOTSECURED;

		if(owner == nodeOwner::PLAYER)
		{
			anims->playAnimation("playerBaseIdleAnim");

			setTexture(anims->getCurrentAnimation()->getTexture());

		}else if(owner == nodeOwner::FINISH) {
			anims->playAnimation("finishBaseIdleAnim");

			setTexture(anims->getCurrentAnimation()->getTexture());
		}else if(owner == nodeOwner::ENEMY) {
			anims->playAnimation("enemyBaseIdleAnim");

			setTexture(anims->getCurrentAnimation()->getTexture());
		}else {
			//add animation for neutral nones entity
			//anims->playAnimation("NutralNodeAnimation");
			anims->playAnimation("nutralNodeAnim");
			setTexture(anims->getCurrentAnimation()->getTexture());
		}
	}

	void update(float frameTime);
	void draw(ID3DXSprite* sprite);
	void handleMessage(Message message); 

	//setters and getters
	int getID() { return ID; }
	void setID(int n) { ID = n; }
	
	int getWeight() { return weight; }
	void setWeight(int n) { weight = n; }

	std::list<Node*> getConnectedNodes() { return connectedNodes;  }
	void addConnectedNodes(std::list<Node*>*); 
	void addConnectedNode(Node* newNode);
	void clearNodes();

	D3DXVECTOR3 getPosition() { return position; }
	void setPosition(D3DXVECTOR3 n) { position = n; }

	nodeOwner getNodeState() { return this->owner; }
	void setNodeState(nodeOwner n) { this->owner = n; }

	hackedState getHackingState() { return this->hacking; }
	void setHackingState(hackedState n) { this->hacking = n; }

	secureState getSecuringState() { return this->securing; }
	void setSecuringState(secureState n) { this->securing = n; }

	int getLevel() { return level; }
	void setLevel(int n) { level = n; }

	int getDistance() { return distance; }
	void setDistance(int n) { distance = n; } 

	nodeOwner getOwner() { return owner; } 

	std::hash_map<Node*, float> getConnections() { return this->connections; }
	void setConnectionTime(Node* n, float f) { connections[n] = f; }

	float getConnectionTime(Node* n) { return n->getDistance(); } 
};
